home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Speccy ClassiX 1998
/
Speccy ClassiX 98.iso
/
amiga_system
/
the_aminet
/
dev
/
gcc
/
ixemulsrc.lha
/
ixemul-41.4
/
library
/
ix_open.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-05-28
|
7KB
|
213 lines
/*
* This file is part of ixemul.library for the Amiga.
* Copyright (C) 1991, 1992 Markus M. Wild
* Portions Copyright (C) 1994 Rafael W. Luebbert
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: ix_open.c,v 1.7 1994/06/19 15:13:03 rluebbert Exp $
*
* $Log: ix_open.c,v $
* Revision 1.7 1994/06/19 15:13:03 rluebbert
* *** empty log message ***
*
* Revision 1.5 1992/10/20 16:20:56 mwild
* initialize malloc-region pointer (necessary after vfork-change)
*
* Revision 1.4 1992/08/09 20:53:36 amiga
* clean up
*
* Revision 1.3 1992/05/20 01:31:30 mwild
* move atexit(_cleanup) into ix_get_vars2 after stdio initialisation
*
* Revision 1.2 1992/05/18 12:20:27 mwild
* change async mp to be global
*
* Revision 1.1 1992/05/14 19:55:40 mwild
* Initial revision
*
*/
#define KERNEL
#include "ixemul.h"
#include "kprintf.h"
#undef u
#include <hardware/intbits.h>
#include <exec/memory.h>
#define BASE_EXT_DECL
#define BASE_EXT_DECL0
#define BASE_PAR_DECL struct ixemul_base *ixbase,
#define BASE_PAR_DECL0 struct ixemul_base *ixbase
#define BASE_NAME ixbase->ix_intui_base
#include <inline/intuition.h>
extern void launch_glue (), switch_glue ();
extern void trap_20 ();
extern void trap_00 ();
extern int ix_timer();
extern void mp_interrupt ();
extern struct ExecBase *SysBase;
struct ixemul_base *
ix_open (struct ixemul_base *ixbase)
{
/* here we must initialize our `user' structure */
struct user *u;
/* an errno for those that later don't set it in ix_startup() */
static int default_errno;
struct Task *me;
me = SysBase->ThisTask;
u = (struct user *) kmalloc (sizeof (struct user));
if (u)
{
curproc = u;
/* bzero is safe, ie. doesn't need to reference struct user */
bzero (u, sizeof (struct user));
/* remember old state */
u->u_otask_flags = me->tc_Flags;
u->u_olaunch = me->tc_Launch;
u->u_oswitch = me->tc_Switch;
u->u_otrap_code = me->tc_TrapCode;
u->u_otrap_data = me->tc_TrapData;
NewList ((struct List *) & u->u_md.md_list);
u->u_mdp = & u->u_md;
KPRINTF (("ix_open: curproc = $%lx, ix_open @$lx\n", curproc, ix_open));
me->tc_TrapData = (APTR) u;
if (betterthan68000())
me->tc_TrapCode = trap_20;
else
me->tc_TrapCode = trap_00;
/* setup the p_sigignore mask correctly */
siginit (u);
me->tc_SigRecvd &= 0x0fff;
/* this library is a replacement for any c-library, thus we should be
* started at the START of a program, and out of 16 available signals
* this calls has to simply succeed... I know I'm a lazy guy ;-) */
u->u_sleep_sig = AllocSignal (-1);
/* network related functions are only enabled if InetBase is != 0 */
u->u_InetBase = OpenLibrary ("inet.library", 5);
if (u->u_InetBase)
{
u->u_sigurg = AllocSignal (-1);
u->u_sigio = AllocSignal (-1);
}
me->tc_Launch = launch_glue;
me->tc_Switch = switch_glue;
me->tc_Flags |= TF_LAUNCH | TF_SWITCH;
u->u_itimerint.is_Node.ln_Type = NT_INTERRUPT;
u->u_itimerint.is_Node.ln_Name = me->tc_Node.ln_Name;
u->u_itimerint.is_Node.ln_Pri = 1;
u->u_itimerint.is_Data = (APTR) me;
u->u_itimerint.is_Code = (APTR) ix_timer;
AddIntServer (INTB_VERTB, & u->u_itimerint);
u->u_trace_flags = 1;
u->u_ixbase = ixbase;
u->u_errno = &default_errno;
u->u_sync_mp = (struct MsgPort *) syscall (SYS_CreatePort, 0, 0);
/* the CD storage. since 0 is a valid value for a lock, we use -1 */
u->u_startup_cd = (BPTR)-1;
/* support for subprocesses ala Unix */
/* each process starts out to be in its own process group. vfork()
* scribbles over this to inherit the parents process group instead */
u->p_pgrp = (int) me;
u->p_pptr = (struct Process *) 1; /* hi init ;-)) */
u->p_cptr =
u->p_osptr =
u->p_ysptr = 0; /* no children to start with */
u->p_vfork_msg = 0;
u->p_zombie_sig = AllocSignal (-1);
NewList ((struct List *) &u->p_zombies);
if (/* u->u_async_mp && */ u->u_sync_mp)
{
u->u_time_req = (struct timerequest *)
syscall (SYS_CreateExtIO, u->u_sync_mp, sizeof (struct timerequest));
if (u->u_time_req)
{
if (!OpenDevice (TIMERNAME, UNIT_MICROHZ,
(struct IORequest *) u->u_time_req, 0))
{
syscall (SYS_gettimeofday, &u->u_start, 0);
/* have to mask out ALL signals until ix_startup has had a
* chance to setup its exit jmp_buf. If not, _longjmp will
* generate a longjmp-botch using a not initialized jmpbuf! */
syscall (SYS_sigsetmask, ~0);
/* if enabled, set the red zone pointer for stack watch */
if (ixbase->ix_red_zone_size)
{
struct Process *mep = (struct Process *) me;
struct CommandLineInterface *CLI = BTOCPTR (mep->pr_CLI);
u_int stack_size = CLI ? CLI->cli_DefaultStack * 4 : mep->pr_StackSize;
/* I guess the above approach to find the correct stack
size will work most of the time. But using tc_Lower
as lower bound would probably not work. Thus I'm using
the current stack value, not the unknown `real' top stack
as top and subtract the stack_size to get to the bottom */
if (stack_size > ixbase->ix_red_zone_size)
u->u_red_zone = (void *)(get_sp () - stack_size
+ ixbase->ix_red_zone_size);
}
return ixbase;
}
/* couldn't open the timer device */
syscall (SYS_DeleteExtIO, u->u_time_req);
}
}
if (u->u_sync_mp)
syscall (SYS_DeletePort, u->u_sync_mp);
RemIntServer (INTB_VERTB, & u->u_itimerint);
me->tc_Flags = u->u_otask_flags;
me->tc_Launch = u->u_olaunch;
FreeSignal (u->u_sleep_sig);
/* all_free() MUST come before we remove the pointer to u */
all_free ();
me->tc_TrapCode = u->u_otrap_code;
me->tc_TrapData = u->u_otrap_data;
kfree (u);
}
return 0;
}